# -*- coding: utf-8 -*
#!/usr/bin/python3

#
#   路径不能有中文
#   暂时只能支持windows下的路径
#   路径保持双反斜杠   
#
#   生成apk流程
#   1.生成R.java类
#   2.将所有java代码打包为.class文件
#   3.生成classes.dex文件
#   4.打包所有资源为apk资源包
#   5.将apk资源包打包为未签名的apk包
#   6.对未签名的apk包进行签名
# 

import os
import sys
import shutil

args = sys.argv
for index in iter(range(len(args))):
    print(index,"    ",args[index])

#os.system("pause")

# 安卓工程存放路径
android_eclipse_project_path = "D:/U3d/suzhou/Android_Copy"

# unity导出的安卓工程路径
unity_build_android_eclipse_project_path = args[1]

# javac工具位置，如果在环境变量能够访问javac则直接填写javac即可
javac = "javac"
java = "java"
jarsigner = "jarsigner"

# aapt工具位置，一般存放在sdk路径下
aapt = "E:/Java/SDKManager/build-tools/25.0.2/aapt"

# 打包安卓工程的基础jar包
android_jar = "E:/Java/SDKManager/platforms/android-25/android.jar"

# 生成dex工具所在位置
dx = "E:/Java/SDKManager/build-tools/25.0.1/dx.bat"

# 打包未签名的apk文件的jar包
sdklib = "E:/Java/SDKManager/tools/lib/sdklib.jar"

# 签名文件存放位置 跟 签名的别名和密码
keystore_file_path = "D:/U3d/suzhou/Android_Copy/signedFile/lakagame.keystore"
keystore_passwd = "laka1808"
keystore_name = "laka"

# 打包出来的apk位置 以及apk名称
save_apk_path = "D:/U3d/suzhou/Android_Copy/SaveApk"
apk_name = "test_test"


# 程序默认会将 android_eclipse_project_path 的libs目录下所有的jar包添加到打包工程
# 如果需要添加其它地方的jar包，就将jar包的位置放在下面的json中
# 如果填写的是目录则会遍历目录下所有的jar包，添加的jar包文件则添加单独的一个jar包
extra_jars = [
    "D:/U3d\suzhou/Android_Copy/assets/yayavoice_for_assets.jar",
    "D:/U3d/suzhou/PushSDK/libs"
]




# 拼接cmd
# return cmd
def MakeCmd(_command,*args):
    cmd = _command
    for index in iter(range(len(args))):
        cmd = cmd + " " + args[index]
    
    return cmd

# 存储生成classes的临时bin目录
def GetSaveBinPath():
    return android_eclipse_project_path + "/TempForder/bin"

def GetSaveGenPath():
    return android_eclipse_project_path + "/TempForder/gen"

def GetSaveDexFullPath():
    return GetSaveBinPath() + "/" + "classes.dex"

# 获取所有jar包文件的完整路径
def GetJarFullPathList():
    
    full_paths = []

    def GetJarPath(file_dir):
        for tab in os.walk(file_dir):
            temp_list = tab[2]
            for index in iter(range(len(temp_list))):
                file_path = tab[0] + "/" + temp_list[index]
                if os.path.isfile(file_path) and '.jar' in os.path.splitext(file_path)[1]:
                    full_paths.append(file_path)
    

    # 添加android_eclipse_project_path 的libs目录下所有的jar
    GetJarPath(android_eclipse_project_path + "/libs")

    # 添加额外的jar包文件
    for index in iter(range(len(extra_jars))):
        temp_extra_path = extra_jars[index]

        # 如果填写的是目录则会遍历目录下所有的jar包，添加的jar包文件则添加单独的一个jar包
        if os.path.isfile(temp_extra_path):
            if '.jar' in os.path.splitext(temp_extra_path)[1]:
                full_paths.append(temp_extra_path)

        elif os.path.isdir(temp_extra_path):
           GetJarPath(temp_extra_path)
    
    return full_paths


def GetAllJavaDirPath():
    
    java_dir_path = []

    def GetJarPath(file_dir):
        for tab in os.walk(file_dir ):
            temp_list = tab[2]
            for index in iter(range(len(temp_list))):
                if ".java" in temp_list[index]:
                    java_dir_path.append(tab[0])
                    break;

    # 获取android_eclipse_project_path 下所有的src目录文件
    GetJarPath(android_eclipse_project_path + "/src")

    # 获取R.java
    temp_path = GetSaveGenPath()
    GetJarPath(temp_path)
    return java_dir_path

def GetResPath():
    return android_eclipse_project_path + "/" + "res"

def GetAssetsPath():
    return android_eclipse_project_path + "/" + "assets"

def GetAndroidManifestXmlPath():
    return android_eclipse_project_path + "/" + "AndroidManifest.xml"

def GetSaveAPKResoucesName():
    return "AutoPackResources"

def GetLibSoDir():
    # 添加android_eclipse_project_path 的libs目录下所有的.so
    return android_eclipse_project_path + "/libs"


def GetSaveApkDirPath():
    return android_eclipse_project_path + "/TempForder/ApkFolder"

# 拼接列表为字符串
def ChangeListToString(data_of_list_or_tuple,split_symbol):
    txt = ""
    length = len(data_of_list_or_tuple)
    for index in iter(range(len(data_of_list_or_tuple))):
        txt = txt + str(data_of_list_or_tuple[index]) + split_symbol

    return txt









#1.生成R.java类
# R.java 文件必须的要在gen目录下，要不然下一步骤编译class时找不到R
def CreateRClass():
    save_gen = GetSaveGenPath()
    res = GetResPath()
    assets = GetAssetsPath()
    android_manifest_xml_path = GetAndroidManifestXmlPath()

    command = MakeCmd(aapt,"package","-m","-J",save_gen,"-A",assets,"-S",res,"-I",android_jar,"-M",android_manifest_xml_path)
    print("CreateRClass Command -> \n",command)
    os.system(command)



# 2.将所有java代码打包为.class文件
# 生成的文件必须的要在bin目录下，要不然下一步骤编译class时找不到R
def CompileClass():
    target_sdk = "1.7"
    save_bin = GetSaveBinPath()
    java_dir_list = GetAllJavaDirPath()
    java_dir = ChangeListToString(java_dir_list,"/*.java ")
    jar_list = GetJarFullPathList()
    jar_paths = ChangeListToString(jar_list,";")

    command = MakeCmd(javac,"-source",target_sdk,"-target",target_sdk,"-g","-verbose","-bootclasspath",android_jar,"-d",save_bin,java_dir,"-classpath",jar_paths)
    print("CompileClass Command -> \n",command)
    #os.system("pause")
    os.system(command)



# 3.生成classes.dex文件
def CreateDexFile():
    output = "--output={0}".format(GetSaveDexFullPath())
    save_bin = GetSaveBinPath()
    jar_list = GetJarFullPathList()
    jar_paths = ChangeListToString(jar_list," ")

    command = MakeCmd(dx,"--dex",output,save_bin,jar_paths)
    print("CreateDexFile Command -> \n",command)
    #os.system("pause")
    os.system(command)



# 4.打包所有资源为apk资源包 
def CreateApkResources():
    save_resouces_full_path = GetSaveBinPath() + "/" + GetSaveAPKResoucesName()
    res = GetResPath()
    assets = GetAssetsPath()
    android_manifest_xml_path = GetAndroidManifestXmlPath()

    command = MakeCmd(aapt,"package","-f","-S",res,"-A",assets,"-I",android_jar,"-M",android_manifest_xml_path,"-F",save_resouces_full_path)
    print("CreateApkResources Command -> \n",command)
    #os.system("pause")
    os.system(command)



# 5.将apk资源包打包为未签名的apk包
def CreateUnSinedApk():
    apk_resources_full_name = GetSaveBinPath() + "/" + GetSaveAPKResoucesName()
    so_path = GetLibSoDir()
    dex_path = GetSaveDexFullPath()
    save_unsigned_apk_full_path = GetSaveApkDirPath() + "/" + "_AutoPack.apk"

    command = MakeCmd(java,"-cp",sdklib,"com.android.sdklib.build.ApkBuilderMain",save_unsigned_apk_full_path,"-v","-u","-z",apk_resources_full_name,"-nf",so_path,"-f",dex_path)
    print("CreateUnSinedApk Command -> \n",command)
    #os.system("pause")
    os.system(command)



# 6.对未签名的apk包进行签名
def CreateSignedApk():
    save_apk_full_path = save_apk_path + "/" + apk_name + ".apk"
    save_unsigned_apk_full_path = GetSaveApkDirPath() + "/" + "_AutoPack.apk"

    command = MakeCmd(jarsigner,"-verbose","-keystore",keystore_file_path,"-storepass",keystore_passwd,"-signedjar",save_apk_full_path,save_unsigned_apk_full_path,keystore_name)
    print("CreateSignedApk Command -> \n",command)
    #os.system("pause")
    os.system(command)


def InitBuildApk():
    if not os.path.isdir(android_eclipse_project_path):
        print("android_eclipse_project_path is not a dir \n ",android_eclipse_project_path)
        return False
    if not os.path.isdir(unity_build_android_eclipse_project_path):
        print("unity_build_android_eclipse_project_path is not a dir \n",sys.argv,"index = 1")
        return False

    if os.path.exists(save_apk_path):
        shutil.rmtree(save_apk_path)
    os.makedirs(save_apk_path)
    

    remove_paths = []
    remove_paths.append(GetSaveBinPath())
    remove_paths.append(GetSaveGenPath())
    remove_paths.append(GetSaveApkDirPath())
    for index in iter(range(len(remove_paths))):
        remove_path = remove_paths[index]
        if os.path.exists(remove_path):
            shutil.rmtree(remove_path)
        os.makedirs(remove_path)

    assert_path = GetAssetsPath()
    print(assert_path)
    if os.path.exists(assert_path):
        shutil.rmtree(assert_path)
    shutil.copytree(unity_build_android_eclipse_project_path + "/" +"assets",assert_path)

    return True

# 删除中途生成已经被废弃的文件
def ClearSignedProcess():
    shutil.rmtree(android_eclipse_project_path + "/TempForder")  
    return



if not InitBuildApk():
    exit()

#1.生成R.java类
CreateRClass()
#os.system("pause")

# 2.将所有java代码打包为.class文件
CompileClass()
#os.system("pause")

# 3.生成classes.dex文件
CreateDexFile()
#os.system("pause")

# 4.打包所有资源为apk资源包 
CreateApkResources()
#os.system("pause")

# 5.将apk资源包打包为未签名的apk包
CreateUnSinedApk()
#os.system("pause")

# 6.对未签名的apk包进行签名
CreateSignedApk()
os.system("pause")

ClearSignedProcess()
#os.system("pause")


# def TestGetJarFullPathList():
    
#     full_paths = []
#     test_fileDir = "D:/U3d/suzhou/Android_Copy"
#     test_extra_jars = ["D:/U3d/suzhou\Android_Copy/assets/yayavoice_for_assets.jar","D:/U3d/suzhou/PushSDK/libs"]

#     def GetJarPath(fileDir):
#         for tab in os.walk(fileDir):
#             temp_list = tab[2]
#             for index in iter(range(len(temp_list))):
#                 file_path = tab[0] + "/" + temp_list[index]
#                 if os.path.isfile(file_path) and '.jar' in os.path.splitext(file_path)[1]:
#                     full_paths.append(file_path)
    

#     # 添加android_eclipse_project_path 的libs目录下所有的jar
#     GetJarPath(test_fileDir + "/libs")

#     # 添加额外的jar包文件
#     for index in iter(range(len(test_extra_jars))):
#         temp_extra_path = test_extra_jars[index]

#         # 如果填写的是目录则会遍历目录下所有的jar包，添加的jar包文件则添加单独的一个jar包
#         if os.path.isfile(temp_extra_path):
#             if os.path.splitext(temp_extra_path)[1] == '.jar':
#                 full_paths.append(temp_extra_path)

#         elif os.path.isdir(temp_extra_path):
#            GetJarPath(temp_extra_path)
    
#     return full_paths

# print("TestGetJarFullPathList \n")
# print(TestGetJarFullPathList())


# def testGetAllJavaDirPath():
#     # 获取android_eclipse_project_path 下所有的src目录文件
#     dir_path = []
#     for tab in os.walk("D:\U3d\suzhou\Android_Copy" + "/src"):
#         temp_list = tab[2]
#         for index in iter(range(len(temp_list))):
#             if ".java" in temp_list[index]:
#                 dir_path.append(tab[0])
#                 break;
#     return dir_path

# print(testGetAllJavaDirPath())